package com.example.housingRentalSystem.controller;

import com.example.housingRentalSystem.bean.Role;
import com.example.housingRentalSystem.bean.User;
import com.example.housingRentalSystem.security.provider.JwtTokenProvider;
import com.example.housingRentalSystem.service.Impl.UserServiceImpl;
import com.example.housingRentalSystem.service.RoleService;
import com.example.housingRentalSystem.utils.ApiResponse;
import com.example.housingRentalSystem.utils.HttpStatus;
import io.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 王硕
 */
@RestController
@RequestMapping("/api/auth")
@Api(tags = "认证管理")
public class AuthController {

    private static final Logger logger = LoggerFactory.getLogger(AuthController.class);

    private final AuthenticationManager authenticationManager;

    @Autowired
    public AuthController(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private RoleService roleService;

    @PostMapping("/login")
    public ApiResponse<String> login(@RequestBody User loginRequest) {
        try {
            logger.debug("Attempting to authenticate user with account: {}", loginRequest.getAccount());

            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(loginRequest.getAccount(), loginRequest.getPassword())
            );

            SecurityContextHolder.getContext().setAuthentication(authentication);

            UserDetails userDetails = userService.loadUserByUsername(loginRequest.getAccount());
            Integer userId = userService.getUserIdByAccount(loginRequest.getAccount());

            String token = jwtTokenProvider.createToken(userId,loginRequest.getAccount(), userDetails.getAuthorities().stream()
                    .map(authority -> authority.getAuthority()).collect(Collectors.toList()));

            logger.info("Successfully authenticated user with account: {}", loginRequest.getAccount());

            return ApiResponse.success("登录成功",token);
        } catch (BadCredentialsException e) {
            return ApiResponse.error(HttpStatus.BAD_REQUEST.getCode(), "账号或密码错误");
        } catch (UsernameNotFoundException e) {
            return ApiResponse.error(HttpStatus.NOT_FOUND.getCode(), "用户不存在");
        } catch (Exception e) {
            logger.error("系统登录异常: {}", e.getMessage());
            return ApiResponse.error(HttpStatus.INTERNAL_SERVER_ERROR.getCode(), "系统繁忙");
        }
    }



    @PostMapping("/register")
    public ApiResponse<String> register(@RequestBody Map<String, Object> request) {
        try {
            String account = (String) request.get("account");
            String password = (String) request.get("password");
            String nickname = (String) request.get("nickname");
            String phone = (String) request.get("phone");
            String email = (String) request.get("email");
            String name = (String) request.get("name");
            String idcard = (String) request.get("idcard");
            List<Map<String, Integer>> roles = (List<Map<String, Integer>>) request.get("roles");

            User user = new User();
            user.setAccount(account);
            user.setPassword(password); // 确保密码加密
            user.setNickname(nickname);
            user.setPhone(phone);
            user.setEmail(email);
            user.setName(name);
            user.setIdcard(idcard);

            userService.save(user); // 确保用户被正确保存

            Integer roleId = roles.get(0).get("roleId");
            Role userRole = roleService.findById(roleId);
            if (userRole == null) {
                return ApiResponse.error(HttpStatus.INTERNAL_SERVER_ERROR.getCode(), "角色不存在");
            }

            roleService.addRoleToUser(user.getAccount(), userRole.getName());

            UserDetails userDetails = userService.loadUserByUsername(user.getAccount());
            Integer userId = userService.getUserIdByAccount(user.getAccount());

            String token = jwtTokenProvider.createToken(userId, user.getAccount(), userDetails.getAuthorities().stream()
                    .map(authority -> authority.getAuthority()).collect(Collectors.toList()));

            return ApiResponse.success(token);
        } catch (RuntimeException e) {
            logger.error("注册失败: {}", e.getMessage(), e);
            return ApiResponse.error(HttpStatus.BAD_REQUEST.getCode(), "注册失败: " + e.getMessage());
        } catch (Exception e) {
            logger.error("注册失败: {}", e.getMessage(), e);
            return ApiResponse.error(HttpStatus.INTERNAL_SERVER_ERROR.getCode(), "注册失败: " + e.getMessage());
        }
    }
    @PostMapping("/resetPwd")
    public ApiResponse<String> resetPwd(@RequestBody Map<String, Object> request) {
        try {
            if (request.get("account") == null || request.get("phone") == null ||
                    request.get("email") == null || request.get("newPassword") == null ||
                    request.get("idCardLastSix") == null) {
                return ApiResponse.error(HttpStatus.BAD_REQUEST.getCode(), "请求参数不完整");
            }

            String account = (String) request.get("account");
            String phone = (String) request.get("phone");
            String email = (String) request.get("email");
            String newPassword = (String) request.get("newPassword");
            String idCardLastSix = (String) request.get("idCardLastSix");

            User user = new User();
            user.setAccount(account);
            user.setPhone(phone);
            user.setEmail(email);
            user.setPassword(newPassword);
            user.setIdCardLastSix(idCardLastSix);

            userService.resetPwd(user);

            UserDetails userDetails = userService.loadUserByUsername(user.getAccount());

            String token = jwtTokenProvider.createToken(
                    user.getId(),
                    user.getAccount(),
                    userDetails.getAuthorities().stream()
                            .map(authority -> authority.getAuthority())
                            .collect(Collectors.toList())
            );

            return ApiResponse.success(token);
        } catch (RuntimeException e) {
            logger.error("密码重置失败: {}", e.getMessage(), e);
            return ApiResponse.error(HttpStatus.BAD_REQUEST.getCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("密码重置失败: {}", e.getMessage(), e);
            return ApiResponse.error(HttpStatus.INTERNAL_SERVER_ERROR.getCode(), "密码重置失败");
        }
    }

    @PostMapping("/changePassword")
    public ApiResponse<String> changePassword(@RequestBody Map<String, Object> request) {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String account = authentication.getName();
            if (request.get("oldPassword") == null || request.get("newPassword") == null) {
                return ApiResponse.error(HttpStatus.BAD_REQUEST.getCode(), "请求参数不完整");
            }

            String oldPassword = (String) request.get("oldPassword");
            String newPassword = (String) request.get("newPassword");

            userService.changePassword(account, oldPassword, newPassword);

            return ApiResponse.success("密码修改成功");
        } catch (BadCredentialsException e) {
            return ApiResponse.error(HttpStatus.UNAUTHORIZED.getCode(), "旧密码错误");
        } catch (Exception e) {
            logger.error("密码修改失败: {}", e.getMessage());
            return ApiResponse.error(HttpStatus.INTERNAL_SERVER_ERROR.getCode(), "系统繁忙");
        }
    }

}